home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 24 / AACD 24.iso / AACD / Sound / LAME / WarpOS / src / frontend / rtp.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-15  |  9.9 KB  |  403 lines

  1. /* $Id: rtp.c,v 1.9 2001/01/15 15:16:08 aleidinger Exp $ */
  2.  
  3. #ifdef HAVE_CONFIG_H
  4. # include <config.h>
  5. #endif
  6.  
  7. #include <stdio.h>
  8.  
  9. #ifdef STDC_HEADERS
  10. # include <stdlib.h>
  11. # include <string.h>
  12. #else
  13. # ifndef HAVE_STRCHR
  14. #  define strchr index
  15. #  define strrchr rindex
  16. # endif
  17. char *strchr (), *strrchr ();
  18. # ifndef HAVE_MEMCPY
  19. #  define memcpy(d, s, n) bcopy ((s), (d), (n))
  20. #  define memmove(d, s, n) bcopy ((s), (d), (n))
  21. # endif
  22. #endif
  23.  
  24. #ifdef HAVE_UNISTD_H
  25. # include <unistd.h>
  26. #endif
  27.  
  28. #include <sys/types.h>
  29. #include <sys/socket.h>
  30. #include <netinet/in.h>
  31. #include <arpa/inet.h>
  32.  
  33. #ifdef WITH_DMALLOC
  34. #include <dmalloc.h>
  35. #endif
  36.  
  37. struct rtpbits {
  38.     int     sequence:16;     /* sequence number: random */
  39.     int     pt:7;            /* payload type: 14 for MPEG audio */
  40.     int     m:1;             /* marker: 0 */
  41.     int     cc:4;            /* number of CSRC identifiers: 0 */
  42.     int     x:1;             /* number of extension headers: 0 */
  43.     int     p:1;             /* is there padding appended: 0 */
  44.     int     v:2;             /* version: 2 */
  45. };
  46.  
  47. struct rtpheader {           /* in network byte order */
  48.     struct rtpbits b;
  49.     int     timestamp;       /* start: random */
  50.     int     ssrc;            /* random */
  51.     int     iAudioHeader;    /* =0?! */
  52. };
  53.  
  54. void
  55. initrtp (struct rtpheader *foo)
  56. {
  57.     foo->b.v        =  2;
  58.     foo->b.p        =  0;
  59.     foo->b.x        =  0;
  60.     foo->b.cc       =  0;
  61.     foo->b.m        =  0;
  62.     foo->b.pt       = 14;     /* MPEG Audio */
  63. #ifdef FEFE
  64.     foo->b.sequence = 42;
  65.     foo->timestamp  =  0;
  66. #else
  67.     foo->b.sequence = rand () & 65535;
  68.     foo->timestamp  = rand ();
  69. #endif
  70.     foo->ssrc       = rand ();
  71.     foo->iAudioHeader = 0;
  72. }
  73.  
  74. int
  75. sendrtp (int fd, struct sockaddr_in *sSockAddr, struct rtpheader *foo,
  76.          const void *data, int len)
  77. {
  78.     char   *buf = alloca (len + sizeof (struct rtpheader));
  79.     int    *cast = (int *) foo;
  80.     int    *outcast = (int *) buf;
  81.     outcast[0] = htonl (cast[0]);
  82.     outcast[1] = htonl (cast[1]);
  83.     outcast[2] = htonl (cast[2]);
  84.     outcast[3] = htonl (cast[3]);
  85.     memmove (buf + sizeof (struct rtpheader), data, len);
  86.     return sendto (fd, buf, len + sizeof (*foo), 0,
  87.                    (struct sockaddr *) sSockAddr, sizeof (*sSockAddr));
  88. /*  return write(fd,buf,len+sizeof(*foo))==len+sizeof(*foo); */
  89. }
  90.  
  91. /* create a sender socket. */
  92. int
  93. makesocket (char *szAddr, unsigned short port, unsigned char TTL,
  94.             struct sockaddr_in *sSockAddr)
  95. {
  96.     int     iRet, iLoop = 1;
  97.     struct sockaddr_in sin;
  98.     unsigned char    cTtl = TTL;
  99.     char    cLoop = 0;
  100.     unsigned int tempaddr;
  101.  
  102.     int     iSocket = socket (AF_INET, SOCK_DGRAM, 0);
  103.     if (iSocket < 0) {
  104.         fprintf (stderr, "socket() failed.\n");
  105.         exit (1);
  106.     }
  107.  
  108.     tempaddr = inet_addr (szAddr);
  109.     sSockAddr->sin_family = sin.sin_family = AF_INET;
  110.     sSockAddr->sin_port = sin.sin_port = htons (port);
  111.     sSockAddr->sin_addr.s_addr = tempaddr;
  112.  
  113.     iRet = setsockopt (iSocket, SOL_SOCKET, SO_REUSEADDR, &iLoop, sizeof (int));
  114.     if (iRet < 0) {
  115.         fprintf (stderr, "setsockopt SO_REUSEADDR failed\n");
  116.         exit (1);
  117.     }
  118.  
  119.     if ((ntohl (tempaddr) >> 28) == 0xe) {
  120.         /* only set multicast parameters for multicast destination IPs */
  121.         iRet =
  122.             setsockopt (iSocket, IPPROTO_IP, IP_MULTICAST_TTL, &cTtl,
  123.                         sizeof (char));
  124.         if (iRet < 0) {
  125.             fprintf (stderr,
  126.                      "setsockopt IP_MULTICAST_TTL failed.  multicast in kernel?\n");
  127.             exit (1);
  128.         }
  129.  
  130.         cLoop = 1;      /* !? */
  131.         iRet = setsockopt (iSocket, IPPROTO_IP, IP_MULTICAST_LOOP,
  132.                            &cLoop, sizeof (char));
  133.         if (iRet < 0) {
  134.             fprintf (stderr,
  135.                      "setsockopt IP_MULTICAST_LOOP failed.  multicast in kernel?\n");
  136.             exit (1);
  137.         }
  138.     }
  139.  
  140.     return iSocket;
  141. }
  142.  
  143.  
  144.  
  145.  
  146. #if 0
  147. //
  148. // code contributed by Anonymous source.  Supposed to be much better
  149. // then original code, but only seems to run on windows with MSVC.  
  150. // and I cannot test it
  151. //
  152. #include <stdlib.h>
  153. #include <string.h>
  154. #include <netinet/in.h>
  155. #include <unistd.h>
  156. #include <stdio.h>
  157. #include <sys/types.h>
  158. #include <sys/socket.h>
  159. #include <arpa/inet.h>
  160.  
  161. struct rtpbits {
  162.   int sequence:16;    /* sequence number: random */
  163.   int pt:7;    /* payload type: 14 for MPEG audio */
  164.   int m:1;    /* marker: 0 */
  165.   int cc:4;    /* number of CSRC identifiers: 0 */
  166.   int x:1;    /* number of extension headers: 0 */
  167.   int p:1;    /* is there padding appended: 0 */
  168.   int v:2;    /* version: 2 */
  169. };
  170.  
  171. struct rtpheader {    /* in network byte order */
  172.   struct rtpbits b;
  173.   int timestamp;    /* start: random */
  174.   int ssrc;        /* random */
  175.   int iAudioHeader;    /* =0?! */
  176. };
  177.  
  178. void
  179. rtp_initialization
  180. (
  181.     struct rtpheader *foo
  182. )
  183. {
  184.   foo->b.v=2;
  185.   foo->b.p=0;
  186.   foo->b.x=0;
  187.   foo->b.cc=0;
  188.   foo->b.m=0;
  189.   foo->b.pt=14;        /* MPEG Audio */
  190. #ifdef FEFE
  191.   foo->b.sequence=42;
  192.   foo->timestamp=0;
  193. #else
  194.   foo->b.sequence=rand() & 65535;
  195.   foo->timestamp=rand();
  196. #endif
  197.   foo->ssrc=rand();
  198.   foo->iAudioHeader=0;
  199. }
  200.  
  201. int
  202. rtp_send
  203. (
  204.     SOCKET s,
  205.     struct rtpheader *foo,
  206.     void *data,
  207.     int len
  208. )
  209. {
  210.     char *buffer=malloc(len+sizeof(struct rtpheader));
  211.     int *cast=(int *)foo;
  212.     int *outcast=(int *)buffer;
  213.     int count, size ;
  214.  
  215.     outcast[0]=htonl(cast[0]);
  216.     outcast[1]=htonl(cast[1]);
  217.     outcast[2]=htonl(cast[2]);
  218.     outcast[3]=htonl(cast[3]);
  219.     memmove (buffer+sizeof(struct rtpheader),data,len);
  220. //    return sendto (fd,buf,len+sizeof(*foo),0,(struct sockaddr *)sSockAddr,sizeof(*sSockAddr));
  221. /*  return write(fd,buf,len+sizeof(*foo))==len+sizeof(*foo); */
  222.     size = len + sizeof (*foo) ;
  223.     count = send (s, buffer, size, 0) ;
  224.     free (buffer) ;
  225.  
  226.     return count != size ;
  227. }
  228.  
  229. /* create a sender socket. */
  230. int
  231. rtp_socket
  232. (
  233.     SOCKET *ps,
  234.     char *address,
  235.     unsigned short port,
  236.     int TTL
  237. )
  238. {
  239. //    int iRet ;
  240.     int iLoop = 1 ;
  241. //    struct  sockaddr_in sin ;
  242.     char    cTTL = (char)TTL ;
  243.     char    cLoop=0 ;
  244. //    unsigned int tempaddr ;
  245.     BOOL True = TRUE ;
  246.     INT error ;
  247.     char *c = "" ;
  248.     UINT ip ;
  249.     PHOSTENT host ;
  250.     SOCKET s ;
  251.     SOCKADDR_IN source, dest ;
  252. /*
  253.     int s = socket (AF_INET, SOCK_DGRAM, 0) ;
  254.     if (s < 0)
  255.     {
  256.         fprintf(stderr,"socket() failed.\n");
  257.         exit(1);
  258.     }
  259.  
  260.     tempaddr=inet_addr(address);
  261.     sSockAddr->sin_family = sin.sin_family = AF_INET;
  262.     sSockAddr->sin_port = sin.sin_port = htons(port);
  263.     sSockAddr->sin_addr.s_addr = tempaddr;
  264.  
  265.     iRet = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *) &iLoop, 
  266. sizeof(int));
  267.     if (iRet < 0)
  268.     {
  269.         fprintf(stderr,"setsockopt SO_REUSEADDR failed\n");
  270.         exit(1);
  271.     }
  272.  
  273.     if ((ntohl(tempaddr) >> 28) == 0xe)
  274.     {
  275.         // only set multicast parameters for multicast destination IPs
  276.         iRet = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &cTTL, 
  277. sizeof(char));
  278.         if (iRet < 0) {
  279.             fprintf(stderr,"setsockopt IP_MULTICAST_TTL failed.    multicast 
  280. in kernel?\n");
  281.             exit(1);
  282.         }
  283.  
  284.         cLoop = 1;    // !?
  285.         iRet = setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP,
  286.                     &cLoop, sizeof(char));
  287.         if (iRet < 0)
  288.         {
  289.             fprintf(stderr,"setsockopt IP_MULTICAST_LOOP failed.    
  290. multicast in kernel?\n");
  291.             exit(1);
  292.         }
  293.     }
  294. */
  295.     source.sin_family = AF_INET ;
  296.     source.sin_addr.s_addr = htonl (INADDR_ANY) ;
  297.     source.sin_port = htons (0) ;
  298.  
  299.     dest.sin_family = AF_INET;
  300.     dest.sin_addr.s_addr = inet_addr (address) ;
  301.  
  302.     if (!strcmp (address, "255.255.255.255"))
  303.     {
  304.     }
  305.     else if (dest.sin_addr.s_addr == INADDR_NONE)
  306.     {
  307.         host = gethostbyname (address) ;
  308.  
  309.         if (host)
  310.         {
  311.             dest.sin_addr = *(PIN_ADDR) host->h_addr ;
  312.         }
  313.         else
  314.         {
  315.             printf ("Unknown host %s\r\n", address) ;
  316.             return 1 ;
  317.         }
  318.     }
  319.  
  320.     dest.sin_port = htons ((u_short) port) ;
  321.  
  322.     ip = ntohl (dest.sin_addr.s_addr) ;
  323.  
  324.     if (IN_CLASSA(ip)) c = "class A" ;
  325.     if (IN_CLASSB(ip)) c = "class B" ;
  326.     if (IN_CLASSC(ip)) c = "class C" ;
  327.     if (IN_CLASSD(ip)) c = "class D" ;
  328.     if (ip == INADDR_LOOPBACK) c = "loopback" ;
  329.     if (ip == INADDR_BROADCAST) c = "broadcast" ;
  330.  
  331.     s = socket (AF_INET, SOCK_DGRAM, PF_UNSPEC) ;
  332.  
  333.     if (s == INVALID_SOCKET)
  334.     {
  335.         error = WSAGetLastError () ;
  336.         printf ("socket () error %d\r\n", error) ;
  337.         return error ;
  338.     }
  339.  
  340.     error = setsockopt (s, SOL_SOCKET, SO_REUSEADDR, (const char *) &True, 
  341. sizeof (BOOL)) ;
  342.  
  343.     error = bind (s, (struct sockaddr *) &source, sizeof (source)) ;
  344.  
  345.     if (error == SOCKET_ERROR)
  346.     {
  347.         error = WSAGetLastError () ;
  348.         printf ("bind () error %d\r\n", error) ;
  349.         closesocket (s) ;
  350.         return error ;
  351.     }
  352.  
  353.     if (ip == INADDR_BROADCAST)
  354.     {
  355.         printf ("broadcast %s:%u %s\r\n", inet_ntoa (dest.sin_addr), ntohs 
  356. (dest.sin_port), c) ;
  357.  
  358.         error = setsockopt (s, SOL_SOCKET, SO_BROADCAST, (const char *) 
  359. &True, sizeof (BOOL)) ;
  360.  
  361.         if (error == SOCKET_ERROR)
  362.         {
  363.             error = WSAGetLastError () ;
  364.             printf ("setsockopt (%u, SOL_SOCKET, SO_BROADCAST, ...) error %d\r\n", s, error) ;
  365.             closesocket (s) ;
  366.             return error ;
  367.         }
  368.     }
  369.  
  370.     if (IN_CLASSD(ip))
  371.     {
  372.         printf ("multicast %s:%u %s\r\n", inet_ntoa (dest.sin_addr), ntohs (dest.sin_port), c) ;
  373.  
  374. //        error = setsockopt (s, IPPROTO_IP, IP_MULTICAST_TTL, (const char *) &TTL, sizeof (int)) ;
  375.         error = setsockopt (s, IPPROTO_IP, 3, (const char *) &TTL, sizeof (int)) ;
  376.  
  377.         if (error == SOCKET_ERROR)
  378.         {
  379.             error = WSAGetLastError () ;
  380.             printf ("setsockopt (%u, IPPROTO_IP, IP_MULTICAST_TTL, ...) error %d\r\n", s, error) ;
  381.             closesocket (s) ;
  382.             return error ;
  383.         }
  384.     }
  385.  
  386.     error = connect (s, (PSOCKADDR) &dest, sizeof (SOCKADDR_IN)) ;
  387.  
  388.     if (error == SOCKET_ERROR)
  389.     {
  390.         printf ("connect: error %d\n", WSAGetLastError ()) ;
  391.         closesocket (s) ;
  392.         return error ;
  393.     }
  394.  
  395.     *ps = s ;
  396.  
  397.     return 0 ;
  398. }
  399.  
  400.  
  401.  
  402. #endif
  403.